package com.chuangjian.hire.common.exption;

import com.chuangjian.hire.common.dto.R;
import com.chuangjian.hire.common.exceptionEnum.ApiExceptionEnum;
import com.chuangjian.hire.common.exceptionEnum.InnerExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice
public class UnionExceptionHandler {

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    public R handleOtherException(Exception exception) {
        if (exception instanceof ApiException) {
            ApiException apiException = (ApiException) exception;
            log.warn("请求RUI:{} : {} {}", getRequestPath(), apiException.getErrCode(), apiException.getMessage());
            return new R(apiException);
        } else if (exception instanceof MethodArgumentNotValidException) {
            log.warn("【请求参数异常捕获】" + ExceptionUtils.getStackTrace(exception));
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) exception;
            FieldError fieldError = ex.getBindingResult().getFieldErrors().get(0);
            ApiException apiException = new ApiException(ApiExceptionEnum.REQUEST_PARAM_IS_ERROR, fieldError.getDefaultMessage());
            return new R(apiException);
        }
        log.error("请求URI:{} ", getRequestPath(), exception);
        return new R(InnerExceptionEnum.BASE_ERROR);
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = ConstraintViolationException.class)
    public Object MethodArgumentNotValidHandler(ConstraintViolationException exception) {
        //按需重新封装需要返回的错误信息
        String collect = exception.getConstraintViolations().stream().map(it -> it.getMessage()).collect(Collectors.joining(" | "));
        log.warn("请求[{}]参数错误[{}]", getRequestPath(), collect);
        return R.builder().errCode(ApiExceptionEnum.ERROR_PARAM.getCode()).msg(collect).build();
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Object MethodArgumentNotValidHandler(MethodArgumentNotValidException exception) {
        //按需重新封装需要返回的错误信息
        String collect = exception.getBindingResult().getFieldErrors().stream().map(error -> {
//            ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
//            invalidArgument.setDefaultMessage(error.getDefaultMessage());
//            invalidArgument.setField(error.getField());
//            invalidArgument.setRejectedValue(error.getRejectedValue());
//            return invalidArgument;
            return error.getDefaultMessage();
        }).collect(Collectors.joining(" | "));
        log.warn("请求[{}]参数错误[{}]", getRequestPath(), collect);
        return R.builder().errCode(ApiExceptionEnum.ERROR_PARAM.getCode()).msg(collect).build();
    }

    public static String getRequestPath() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) return " ";
        HttpServletRequest request = requestAttributes.getRequest();
        String requestURI = request.getRequestURI();
        return requestURI;
    }
}
